var common={
    cache:null,
    removeCache:function (){
        this.cache=null;
    },
    removeByKey:function (key){
        if(this.cache){
            this.cache.delete(key);
        }
    },
    init:function (){
        this.cache=new Map();
        this.initClick();
    },
    getDomById:function (selector){
        if(this.cache==null){
            this.init();
        }
        if (this.cache.has(selector)) {
            return this.cache.get(selector);
        }
        const element = document.querySelector('#'+selector);
        if (element) {
            this.cache.set(selector, element);
        }
        return element || null;
    },
    getDomByClassName(className){
        if (this.cache.has(className)) {
            return this.cache.get(className);
        }
        const elements = document.querySelectorAll('.'+className);
        if (elements.length > 0) {
            this.cache.set(className, elements);
        }
        return elements.length > 0 ? elements : null;
    },
    getDomByAttrName(attr) {
        // 如果缓存中存在，直接返回
        if (this.cache.has(attr)) {
            return this.cache.get(attr);
        }
        // 查询 DOM
        const elements = document.querySelectorAll(`[${attr}]`);
        // 如果找到元素，缓存它
        if (elements.length > 0) {
            this.cache.set(attr, elements);
        }
        return elements.length > 0 ? elements : null;
    },
    addClick:function (value,callback){
        let attr='attr-click';
        let clickList=document.querySelectorAll(`[${attr}]`);
        clickList.forEach((e)=>{
            const attrValue = e.getAttribute('attr-click');
            if(attrValue===value){
                e.addEventListener('click',function (e){
                    e.preventDefault();
                    callback(e);
                });
            }
        })
    },
    addUploadClick:function (value,callback){
        let attr='upload-click';
        let attrList=document.querySelectorAll(`[${attr}]`);
        if(attrList){
            attrList.forEach((e)=>{
                const accept=e.getAttribute('accept');
                const fileInput = document.createElement('input');
                fileInput.type = 'file';
                fileInput.style.display='none';
                fileInput.multiple = true; // 允许多文件选择
                if(accept){
                    fileInput.accept=accept;
                }
                // 将文件输入框添加到 DOM 中
                e.parentNode.insertBefore(fileInput, e.nextSibling);
                const attrValue = e.getAttribute('upload-click');
                e.addEventListener('click', function(event) {
                    event.preventDefault();
                    fileInput.click();
                })
                if(callback){
                    fileInput.addEventListener('change', (event) => {
                        event.preventDefault();
                        const files = event.target.files; // 获取选择的文件
                        if (files.length > 0) {
                            callback(files);
                        }
                    })
                }else {
                    if (typeof window[attrValue] === 'function') {
                        fileInput.addEventListener('change', (event) => {
                            event.preventDefault();
                            const files = event.target.files; // 获取选择的文件
                            if (files.length > 0) {
                                window[attrValue](files);
                            }
                        })
                    }
                }
            })
        }
    },
    reflushClick:function (){
        this.init();
    },
    initClick:function (){
        let clickList=this.getDomByAttrName('attr-click');
        if(clickList){
            clickList.forEach((e)=>{
                const attrValue = e.getAttribute('attr-click');
                if (typeof window[attrValue] === 'function') {
                    e.addEventListener('click', function(event) {
                        event.preventDefault();
                        window[attrValue]();
                    })
                } else {
                    console.log('方法' + attrValue + '不存在');
                }
            })
        }
        let uploadClickList=this.getDomByAttrName('upload-click');
        if(uploadClickList){
            uploadClickList.forEach((e)=>{
                const accept=e.getAttribute('accept');
                const fileInput = document.createElement('input');
                fileInput.type = 'file';
                fileInput.style.display='none';
                fileInput.multiple = true; // 允许多文件选择
                if(accept){
                    fileInput.accept=accept;
                }
                // 将文件输入框添加到 DOM 中
                e.parentNode.insertBefore(fileInput, e.nextSibling);
                const attrValue = e.getAttribute('upload-click');

                e.addEventListener('click', function(event) {
                    event.preventDefault();
                    fileInput.click();
                })
                if (typeof window[attrValue] === 'function') {
                    fileInput.addEventListener('change', (event) => {
                        const files = event.target.files; // 获取选择的文件
                        if (files.length > 0) {
                            window[attrValue](files);
                        }
                    })
                }else {
                    console.log('方法' + attrValue + '不存在');
                }
            })
        }
    },
    //dom切换(1false,2true)
    elementClickSwitch:function (dom01,dom02,callback){
        let b=false;
        if(dom01){
            dom01.style.display="block";
            dom01.addEventListener("click",(e)=>{
                dom01.style.display="none";
                if(dom02){
                    dom02.style.display="block";
                }
                b=true;
                if(callback){
                    callback(b);
                }
            })
        }
        if(dom02){
            dom02.style.display="none";
            dom02.addEventListener("click",(e)=>{
                dom02.style.display="none";
                if(dom01){
                    dom01.style.display="block";
                }
                b=false;
                if(callback){
                    callback(b);
                }
            })
        }
    },
    //元素获取焦点添加class和失去焦点移除class
    elementFocusBlurCls:function (dom,cls,focuscallback,blurcallback){
        console.log("添加焦点事件")
        // 获取焦点时触发
        dom.addEventListener("focus", (e) => {
            if(cls){
                dom.classList.add(cls);
            }
            if(focuscallback){
                focuscallback(e.target)
            }
        });
        // 失去焦点时触发
        dom.addEventListener("blur", (e) => {
            if(cls){
                dom.classList.remove(cls);
            }
            if(blurcallback){
                blurcallback(e.target);
            }
        });
    },
    //监听元素进入视口
    elementInViewport:function (dom,callback){
        const ob = new IntersectionObserver((entries) => {
            entries.forEach(entry => {
                if (entry.isIntersecting) {
                    console.log('元素进入视口', entry.target);
                    if(callback){
                        callback(entry.target)
                    }
                }else {
                    console.log('元素离开视口', entry.target);
                }
            });
        });
        ob.observe(dom);
    },
    //获取可见区域
   getViewportDistance:function(element) {
    const rect = element.getBoundingClientRect();
    const viewportHeight = window.innerHeight;
        return {
            // 元素顶部到可视区域顶部的距离（正数=在视窗内，负数=在视窗外）
            top: rect.top,

            // 元素底部到可视区域底部的距离（正数=在视窗内，负数=在视窗外）
            bottom: rect.bottom - viewportHeight,

            // 可视区域内的可见高度
            visibleHeight: Math.min(rect.bottom, viewportHeight) - Math.max(rect.top, 0)
        };
    },
    loadScript:function (url){
        return new Promise((resolve, reject) => {
            const script = document.createElement('script');
            script.src = url;
            script.type = 'text/javascript';

            // 加载成功
            script.onload = () => resolve(script);

            // 加载失败
            script.onerror = () => reject(new Error(`无法加载脚本: ${url}`));

            document.head.appendChild(script);
        });
    },
    //判断光标是否在某个元素下
    isCursorInElement:function (targetElement){
        // 获取当前选中的内容或光标位置
        const selection = window.getSelection();

        // 如果没有选中内容或光标，返回 false
        if (!selection || selection.rangeCount === 0) {
            return false;
        }

        // 获取选中内容或光标的起始节点
        const anchorNode = selection.anchorNode;
        console.log(anchorNode);
        // 检查焦点元素是否在目标元素内
        return targetElement.contains(anchorNode);
    },
    //在光标处添加dom
    insertDomAtCursor:function (dom){
        const selection = window.getSelection();
        if (selection.rangeCount > 0) {
            const range = selection.getRangeAt(0);
            range.deleteContents();// 删除原有文本
            range.insertNode(dom);// 插入新的dom
        }
    },
    //根据属性名，移除数组里面的某个值
    arrRemoveByPropertyValue:function (arr,prop, value){
        let index;
        while ((index = arr.findIndex(item => item[prop] === value)) !== -1) {
            arr.splice(index, 1);
        }
    },
    //判断arr里面的对象属性里面是否有某个值
    arrFilterByPropertyValue:function (arr,prop, value){
        return arr.filter(obj => obj[prop] === value);
    },
    //生成唯一id
    generateUUID:function (){
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
            const r = (Math.random() * 16) | 0;
            const v = c === 'x' ? r : (r & 0x3) | 0x8;
            return v.toString(16);
        });
    },
    //子关闭父
    childCloseParent:function (className,parentClassName,callback){
        let domList=document.querySelectorAll('.'+className);
        if(domList){
            domList.forEach((e)=>{
                e.addEventListener('click',(e)=>{
                    let parentNode=e.target.parentNode;
                    let bool=true;
                    if(parentNode && parentNode.nodeType===1){
                        while (bool){
                            if(parentNode && parentNode.nodeType===1){
                                let classList=parentNode.classList
                                if(classList.contains(parentClassName)){
                                    const dataset = parentNode.dataset;
                                    parentNode.replaceWith();
                                    bool=false;
                                    if(callback){
                                        callback(dataset);
                                    }
                                }
                            }else {
                                bool=false;
                            }
                            parentNode=parentNode.parentNode;
                        }
                    }
                })
            })
        }
    },
    //1、parentClassName 父class，一般是拖动区域;2、className 单元class,一般是拖动单元; 3、excludeList 排除可能会影响单元项的点击事件
    startDraggable:function (parentClassName,className,excludeList){
        const container = document.querySelector('.'+parentClassName);
        let draggedItem = null;
        //设置子元素的禁止点击
        function childPointerEvents(dom){
            if(dom && dom.nodeType===1){
                dom.childNodes.forEach((node)=>{
                    if(node.nodeType===1){
                        if(excludeList){
                            let classList=node.classList
                            if(classList && classList.length>0){
                                classList.forEach((e)=>{
                                    if(!excludeList.includes(e)){
                                        node.style.pointerEvents="none";
                                    }
                                })
                            }else {
                                node.style.pointerEvents="none";
                            }
                        }else {
                            node.style.pointerEvents="none";
                        }
                        childPointerEvents(node);
                    }
                });
            }
        }
        if(container){
            let domList=document.querySelectorAll('.'+className);
            if(domList){
                domList.forEach((e)=>{
                    e.draggable=true;
                    childPointerEvents(e);
                })
            }
            // 拖动开始
            container.addEventListener('dragstart', (e) => {
                const target = e.target.closest('.'+className); // 找到最近的 .item 元素
                if (target) {
                    draggedItem = target;
                    target.style.opacity = '0.4';
                }
            });
            // 拖动经过其他元素
            container.addEventListener('dragover', (e) => {
                e.preventDefault(); // 必须阻止默认行为
                const target = e.target.closest('.'+className); // 找到最近的 .item 元素
                if (target && target !== draggedItem) {
                    const rect = target.getBoundingClientRect();
                    const offset = e.clientX - rect.left;
                    if (offset > rect.width / 2) {
                        container.insertBefore(draggedItem, target.nextSibling);
                    } else {
                        container.insertBefore(draggedItem, target);
                    }
                }
            });
            // 拖动结束
            container.addEventListener('dragend', (e) => {
                if (draggedItem) {
                    draggedItem.style.opacity = '1';
                    draggedItem = null;
                }
            });
            // 阻止子元素的默认行为（例如 <a> 标签的点击事件）
            container.addEventListener('mousedown', (e) => {
                if (!e.target.classList.contains(className)) {
                    e.preventDefault(); // 阻止子元素的默认行为
                }
            });
        }
    },
    //为elementList添加class绑定
    elementBoundClassClick:function (elementList,clickClass,callback){
        elementList.forEach((e)=>{
            e.addEventListener('click', () => {
                elementList.forEach(ele => {
                    ele.classList.remove(clickClass);
                })
                e.classList.add(clickClass);
                if(callback){
                    callback(e);
                }
            })
        })
    },
    //显示在某个元素的上方
    elementBoundTargetTopShow:function (sourceDom,targetDom){
        targetDom.style.position ='absolute';
        targetDom.style.display = 'block';
        //获取元素在屏幕里的可见地方
        var rect = sourceDom.getBoundingClientRect();
        var rect2 = targetDom.getBoundingClientRect();
        console.log("显示在上方："+(rect.top+window.pageYOffset))
        let bottom=rect.top+window.pageYOffset ;
        var left=rect.left+window.screenX;
        targetDom.style.left = left + "px";
        targetDom.style.top = (bottom - (rect2.height+5)) + "px";
    },
    //显示在某个元素的下方
    elementBoundTargetBottomShow:function (sourceDom,targetDom){
        targetDom.style.position ='absolute';
        targetDom.style.display = 'block';
        //获取元素在屏幕里的可见地方
        var rect = sourceDom.getBoundingClientRect();
        let top=rect.bottom +window.pageYOffset;
        var left=rect.left+window.screenX;
        targetDom.style.left = left + "px";
        targetDom.style.top = (top + 5) + "px";
    },
    //在元素下面添加其他元素
    elementBoundTargetBottomClick:function (sourceDom,targetDom){
        sourceDom.addEventListener('click',function(e){
            e.preventDefault();
            operateDom('block');
        })
        sourceDom.addEventListener('mouseout', function(e) {
            leave();
        });
        targetDom.addEventListener('mouseout', function(e) {
            leave();
        });
        function operateDom(showType){
            targetDom.style.position ='absolute';
            targetDom.style.display = showType;
            //获取元素在屏幕里的可见地方
            var rect = sourceDom.getBoundingClientRect();
            let top=rect.bottom + window.window.screenY;
            var left=rect.left+window.screenX;
            targetDom.style.left = left + "px";
            targetDom.style.top = (top + 5) + "px";
        }
        function leave(){
            var sourceDivRect = sourceDom.getBoundingClientRect(); // 获取该div元素相对于视口的位置信息
            var targetDivRect = targetDom.getBoundingClientRect();
            var mouseX = event.clientX; // 获取鼠标当前位置的x坐标
            var mouseY = event.clientY; // 获取鼠标当前位置的y坐标
            if (mouseX >= sourceDivRect.left && mouseX <= sourceDivRect.right && mouseY >= sourceDivRect.top && mouseY <= sourceDivRect.bottom +10 ) {
                console.log('鼠标在sourceDivRect区域内');
            } else if( mouseX >= targetDivRect.left && mouseX <= targetDivRect.right && mouseY >= targetDivRect.top && mouseY <= targetDivRect.bottom){
                console.log('鼠标在targetDivRect区域内');
            } else {
                console.log('两个区域都不在');
                targetDom.style.display = 'none';
                //targetDom.style.visibility = 'hidden';
            }
        }
        operateDom('none');
    }
}